/*
 * CCVisu is a tool for visual graph clustering
 * and general force-directed graph layout.
 * This file is part of CCVisu.
 *
 * Copyright (C) 2005-2012  Dirk Beyer
 *
 * CCVisu is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * CCVisu is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with CCVisu; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Please find the GNU Lesser General Public License in file
 * license_lgpl.txt or http://www.gnu.org/licenses/lgpl.txt
 *
 * Dirk Beyer    (firstname.lastname@uni-passau.de)
 * University of Passau, Bavaria, Germany
 */
package org.sosy_lab.ccvisu.readers;

import java.util.ArrayList;
import java.util.List;

import org.sosy_lab.ccvisu.graph.Relation;
import org.sosy_lab.ccvisu.graph.Tuple;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class SAXHandlerDOXXml extends DefaultHandler {

  private int      xmlLevel      = 0;

  private int      memberLevel   = 1;
  private String   memberId      = "";
  private int      compoundLevel = 1;
  private String   compoundId    = "";

  private Relation relations;

  public SAXHandlerDOXXml(Relation relations) {
    super();
    this.relations = relations;
  }

  /* (non-Javadoc)
   * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
   */
  @Override
  public void startElement(String uri, String localName, String qName,
      Attributes attrs) throws SAXException {

    assert (attrs != null);
    xmlLevel++;


    if (qName.toLowerCase().equals("memberdef") // MEMBERDEF AND
        || qName.toLowerCase().equals("compounddef")) { // COMPOUNDDEF

      // Update current entry.
      String lId = attrs.getValue("id");
      assert (lId != null);
      if (qName.toLowerCase().equals("memberdef")) {
        memberLevel = xmlLevel;
        memberId = lId;
      } else {
        compoundLevel = xmlLevel;
        compoundId = lId;
      }
    }

    if (qName.toLowerCase().equals("basecompoundref")) { // BASECOMPOUNDREF
      // Output this reference.
      assert (xmlLevel == compoundLevel + 1);

      // Super class that we inherit from.
      String baseCompoundId = attrs.getValue("refid");
      if (baseCompoundId == null) {
        baseCompoundId = "UNKNOWN-EXTERNAL";
      }

      // Protection.
      String protection = attrs.getValue("prot");
      assert (protection != null);

      // Virtual.
      String virtual = attrs.getValue("virt");
      assert (virtual != null);

      List<String> newTuple = new ArrayList<String>();
      newTuple.add(compoundId);
      newTuple.add(baseCompoundId);
      newTuple.add(protection);
      newTuple.add(virtual);
      relations.addTuple(new Tuple("BASEDON", newTuple));

    } else if (qName.toLowerCase().equals("references")) { // REFERENCES
      // Output this reference.
      assert (xmlLevel == memberLevel + 1);

      String referenceId = attrs.getValue("refid");
      assert (referenceId != null);

      List<String> newTuple = new ArrayList<String>();
      newTuple.add(memberId);
      newTuple.add(referenceId);
      relations.addTuple(new Tuple("REFERSTO", newTuple));

    } else if (qName.toLowerCase().equals("location")) { // LOCATION
      // Output the location.
      String file = attrs.getValue("file");
      assert (file != null);

      String lineNumber = attrs.getValue("line");
      if (lineNumber == null) {
        lineNumber = "UNKNOWN";
      }

      if (xmlLevel == compoundLevel + 1) {
        List<String> newTuple = new ArrayList<String>();
        newTuple.add(compoundId);
        newTuple.add(file);
        newTuple.add(lineNumber);
        relations.addTuple(new Tuple("LOCATEDAT", newTuple));

      } else {
        assert (xmlLevel == memberLevel + 1);
        assert (xmlLevel == compoundLevel + 3);

        List<String> newTuple = new ArrayList<String>();
        newTuple.add(memberId);
        newTuple.add(file);
        newTuple.add(lineNumber);
        relations.addTuple(new Tuple("LOCATEDAT", newTuple));
      }
    }
  }

  /* (non-Javadoc)
   * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
   */
  @Override
  public void endElement(String uri, String localName, String qName)
      throws SAXException {
    xmlLevel--;
  }
}
